package liumeiya.rbac.view;

import liumeiya.rbac.domain.dto.RoleDto;
import liumeiya.rbac.domain.vo.RoleVo;
import liumeiya.rbac.domain.vo.Result;
import liumeiya.rbac.service.RoleService;

public class RoleView {
    /**
     * 输出角色管理菜单
     */
    public static void printMenu(){
        String menu = """
                ------------------
                     角色管理
               ------------------
               |   0...返回上级   |
               |   1...角色列表   |
               |   2...新建角色   |
               |   3...更新角色   |
               |   4...删除角色   |
               -------------------
               请输入选项：""";
        System.out.print(menu);
    }
    
    public static void printError(String message) {
        System.out.println("\033[31m" + message +"\033[0m");
    }

    /**
     *  视图对象缓存数组
     */
    public static RoleVo[] cache;

    public static void show(){
        String menuChoice;
        do {
            printMenu();
            menuChoice = MainView.input.nextLine();
            switch (menuChoice) {
                case "0" -> printError("已返回上一级菜单");
                case "1" -> list();
                case "2" -> create();
                case "3" -> update();
                case "4" -> delete();
                default -> printError("输入非法，请输入正确的菜单编号！");
            }
        } while (!"0".equals(menuChoice));
    }

    /**
     * 列出所有角色的信息。
     * <p>
     * 本方法调用服务层获取所有角色数据， 并将其存储在缓存中。 然后。输出所有角色的ID、 名称和数据访问范围，
     * 以表格形式显示在控制台中， 供用户查看。
     * </p>
     */
    public static void list() {
        Result result = RoleService.list();

        cache = (RoleVo[]) result.data;

        printError("ID\t角色名称\t角色数据访问范围");

        for (RoleVo role : cache) {
            if (role != null) {
                System.out.printf("%d\t%s\t%s\n", role.id, role.name,role.dataScore);
            }
        }
    }

    /**
     * 创建一个新的角色。
     * <p>
     * 本方法会提示用户输入角色的名称和数据访问范围， 并将这些信息封装到一个 ‘RoleDto’ 对象中。
     * 然后调用服务层的创建方法， 若创建成功， 则输出成功信息并列出当前所有角色; 若失败，则输出错误信息。
     * </p>
     */
    public static void create() {
        //提示用户输入角色名称
        System.out.print("请输入角色名称：");

        String name = MainView.input.nextLine();//获取用户输入的角色名称

        //提示用户输入角色数据访问范围
        System.out.print("请输入角色数据访问范围");
        String dataScore = MainView.input.nextLine();//获取用户输入的角色数据访问范围

        //将用户输入的角色名称和数据访问范围封装到RoleDto对象中
        RoleDto dto = new RoleDto(name, dataScore);

        //调用服务层的创建方法， 创建新的角色
        Result result = RoleService.create(dto);

        // 如果创建操作失败， 输出错误信息
        if (!result.success) {
            System.err.println(result.message);
            return; //结束方法执行
        }

        //创建成功，输出成功信息
        printError(result.message);

        // 列出当前所有角色信息
        list();
    }

    /**
     * 更新指定角色的信息。
     * <p>
     * 本方法会提示用户输入角色的ID， 并验证该ID 是否有效。 然后从缓存中查找对应角色数据
     * 如果未找到角色，提示用户。如果找到角色， 用户可以选择修改角色名称和数据访问范围，若用户没有修改，则保持原值。
     * 更新成功后， 会返回更新结果并列出当前角色列表。
     * </p>
     */
    public static void update() {
        RoleVo role = getCacheById();

        if(role == null) {
            return;
        }
        // 提示用户输入新的角色名称， 按回车表示不修改
        System.out.print("请输入角色名称，直接按回车表示不修改：");
        String name = MainView.input.nextLine();
        // 如果用户没有输入新名称， 保持原名称
        name = "".equals(name) ? role.name : name;

        // 提示用户输入新的角色数据访问范围， 按回车表示不修改
        System.out.print("请输入角色数据访问范围，直接按回车表示不修改：");
        String dataScore = MainView.input.nextLine();
        // 如果用户没有输入新数据访问范围， 保持原数据访问范围
        dataScore = "".equals(dataScore) ? role.dataScore : dataScore;

        // 创建新的 RoleDto 对象， 用于更新角色信息
        RoleDto dto = new RoleDto(name, dataScore);

        // 调用服务层更新角色信息
        Result result = RoleService.update(dto, role.id);

        // 如果更新失败， 显示错误信息
        if (!result.success) {
            System.err.println(result.message);
            return;
        }

        // 更新成功，显示成功消息并列出角色信息
        printError(result.message);
        list(); // 列出更新后的角色列表
    }

    /**
     * 删除指定角色信息
     * <p>
     * 本方法会提示用户输入角色的 ID， 并验证该 ID 是否有效。然后从缓存中查找对应角色数据，
     * 如果未找到角色，则提示用户。 若找到角色，用户需确认是否删除该角色，确认后将删除该角色。
     * 如果删除失败， 则提示失败信息； 删除成功后， 重新列出角色信息。
     * </p>
     */
    public static void delete() {
        RoleVo role = getCacheById();

        if(role == null) {
            return;
        }

        // 提示用户确认是否删除
        System.out.print("请输入'Y'确认删除， 输入其他取消删除：");
        String confirm = MainView.input.nextLine();

        // 如果用户输入的不是'Y'或'y’， 则取消删除
        if (!"Y".equalsIgnoreCase(confirm)) {
            printError("您已取消删除");
            return;
        }

        // 调用服务层进行删除操作
        Result result = RoleService.delete(role.id);

        // 如果删除操作失败，提示错误信息
        if (!result.success) {
            System.err.println(result.message);
            return;
        }

        // 删除成功，输出成功信息并列出当前角色列表
        printError(result.message);
        list();
    }
    public static RoleVo getCacheById() {
        // 提示用户输入角色ID
        System.out.print("请输入ID， ID必须是大于0的整数：");

        // 验证用户输入的ID是否为整数
        if (!MainView.input.hasNextInt()) {
            // 清除无效输入
            MainView.input.nextLine();
            System.err.println("ID必须为整数，请输入整数值");
            return null;
        }

        // 获取用户输入的ID
        int id = MainView.input.nextInt();
        // 清除输入缓存中的换行符
        MainView.input.nextLine();

        // 验证ID 是否大于0
        if (id < 1) {
            System.err.println("ID必须大于0，请重新输入");
            return null;
        }

        // 如果缓存为空，则从服务层查询所有角色信息并缓存
        if (cache == null) {
            // 调用服务层获取角色列表
            Result result = RoleService.list();
            // 将查询到的角色数据缓存
            cache = (RoleVo[]) result.data;
        }

        // 在缓存中查找指定ID 的角色
        RoleVo role = null;
        for (RoleVo item : cache) {
            if (item.id == id) {
                // 找到对应ID的角色，输出角色信息
                printError("该ID对应的数据是：");
                System.out.printf("ID：%d，名称：%s，数据访问范围：%s\n",item.id,item.name, item.dataScore);
                role = item;
                break;
            }
        }

        // 如果未找到角色，则提示用户
        if (role == null) {
            System.err.println("当前没有该ID对应的数据");
            return null;
        }

        return role;
    }
}

